#include "perftools.h"

static struct
{
    uint64_t hit0, hit1, miss;
} icache_count, dcache_count;

void count_cahce()
{
    if (top->dcache_hit0)
        dcache_count.hit0++;
    if (top->dcache_hit1)
        dcache_count.hit1++;
    if (top->dcache_miss0 & top->dcache_miss0)
        dcache_count.miss++;

    if (top->icache_hit0)
        icache_count.hit0++;
    if (top->icache_hit1)
        icache_count.hit1++;
    if (top->icache_miss0 & top->icache_miss1)
        icache_count.miss++;
}

void print_cache_count()
{
    uint64_t icache_hit_cnt = icache_count.hit0 + icache_count.hit1;
    uint64_t icache_miss_cnt = icache_count.miss;

    uint64_t dcache_hit_cnt = dcache_count.hit0 + dcache_count.hit1;
    uint64_t dcache_miss_cnt = dcache_count.miss;

    float icache_hitrate = (float)icache_hit_cnt / (icache_hit_cnt + icache_miss_cnt);
    float dcache_hitrate = (float)dcache_hit_cnt / (dcache_hit_cnt + dcache_miss_cnt);

    printf(ANSI_FMT("\ticache: hit:%ld miss:%ld hit rate:%.03f%%\n", ANSI_FG_GREEN), icache_hit_cnt, icache_miss_cnt, icache_hitrate * 100);
    printf(ANSI_FMT("\tdcache: hit:%ld miss:%ld hit rate:%.03f%%\n", ANSI_FG_GREEN), dcache_hit_cnt, dcache_miss_cnt, dcache_hitrate * 100);
}

static uint32_t icache_busy = 0, dcache_busy = 0, mul_busy = 0, div_busy = 0;
void count_busy()
{
    uint8_t busy = top->Hazards_busy;

    if (busy & 0b00001)
        icache_busy++;
    if (top->mul_unit_ready == 0)
        mul_busy++;
    if (top->div_unit_ready == 0)
        div_busy++;
    if (busy & 0b01000)
        dcache_busy++;
}

void print_busy_count()
{
    printf(ANSI_FMT("busy count info:\n\ttotal_cycles: %d icache:%d dcache:%d mul:%d div:%d\n", ANSI_FG_GREEN), total_cycles, icache_busy, dcache_busy, mul_busy, div_busy);
}